@@ -2,7 +2,7 @@ |
||
2 | 2 |
|
3 | 3 |
from django.contrib import admin |
4 | 4 |
|
5 |
-from photo.models import PhotosInfo, UUIDInfo |
|
5 |
+from photo.models import PhotosInfo, PhotoUUIDInfo, UUIDInfo |
|
6 | 6 |
|
7 | 7 |
|
8 | 8 |
class UUIDInfoAdmin(admin.ModelAdmin): |
@@ -10,6 +10,11 @@ class UUIDInfoAdmin(admin.ModelAdmin): |
||
10 | 10 |
list_filter = ('lensman_id', 'status') |
11 | 11 |
|
12 | 12 |
|
13 |
+class PhotoUUIDInfoAdmin(admin.ModelAdmin): |
|
14 |
+ list_display = ('photo_md5', 'photo_path', 'status', 'created_at', 'updated_at') |
|
15 |
+ list_filter = ('status', ) |
|
16 |
+ |
|
17 |
+ |
|
13 | 18 |
class PhotosInfoAdmin(admin.ModelAdmin): |
14 | 19 |
list_display = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'status', 'created_at', 'updated_at') |
15 | 20 |
list_filter = ('lensman_id', 'status') |
@@ -17,3 +22,4 @@ class PhotosInfoAdmin(admin.ModelAdmin): |
||
17 | 22 |
|
18 | 23 |
admin.site.register(UUIDInfo, UUIDInfoAdmin) |
19 | 24 |
admin.site.register(PhotosInfo, PhotosInfoAdmin) |
25 |
+admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin) |
@@ -0,0 +1,29 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.db import models, migrations |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class Migration(migrations.Migration): |
|
8 |
+ |
|
9 |
+ dependencies = [ |
|
10 |
+ ('photo', '0009_auto_20160907_1018'), |
|
11 |
+ ] |
|
12 |
+ |
|
13 |
+ operations = [ |
|
14 |
+ migrations.CreateModel( |
|
15 |
+ name='PhotoUUIDInfo', |
|
16 |
+ fields=[ |
|
17 |
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
18 |
+ ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), |
|
19 |
+ ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), |
|
20 |
+ ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), |
|
21 |
+ ('photo_md5', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_md5', db_index=True)), |
|
22 |
+ ('photo_path', models.CharField(help_text='\u7167\u7247\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)), |
|
23 |
+ ], |
|
24 |
+ options={ |
|
25 |
+ 'verbose_name': 'photouuidinfo', |
|
26 |
+ 'verbose_name_plural': 'photouuidinfo', |
|
27 |
+ }, |
|
28 |
+ ), |
|
29 |
+ ] |
@@ -27,6 +27,18 @@ class UUIDInfo(CreateUpdateMixin): |
||
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
|
30 |
+class PhotoUUIDInfo(CreateUpdateMixin): |
|
31 |
+ photo_md5 = models.CharField(_(u'photo_md5'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True) |
|
32 |
+ photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片路径') |
|
33 |
+ |
|
34 |
+ class Meta: |
|
35 |
+ verbose_name = _('photouuidinfo') |
|
36 |
+ verbose_name_plural = _('photouuidinfo') |
|
37 |
+ |
|
38 |
+ def __unicode__(self): |
|
39 |
+ return u'{0.pk}'.format(self) |
|
40 |
+ |
|
41 |
+ |
|
30 | 42 |
class PhotosInfo(CreateUpdateMixin): |
31 | 43 |
lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
32 | 44 |
session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True) |
@@ -9,6 +9,7 @@ TimeConvert==1.3.12 |
||
9 | 9 |
cryptography==1.5.2 |
10 | 10 |
django-curtail-uuid==1.0.0 |
11 | 11 |
django-detect==1.0.5 |
12 |
+django-file-md5==1.0.0 |
|
12 | 13 |
django-ip==1.0.0 |
13 | 14 |
django-json-response==1.1.4 |
14 | 15 |
django-logit==1.0.6 |
@@ -4,12 +4,25 @@ import os |
||
4 | 4 |
|
5 | 5 |
import shortuuid |
6 | 6 |
from django.core.files.storage import default_storage |
7 |
+from django.db import transaction |
|
8 |
+from filemd5 import calculate_md5 |
|
7 | 9 |
|
10 |
+from photo.models import PhotoUUIDInfo |
|
8 | 11 |
|
12 |
+ |
|
13 |
+@transaction.atomic |
|
9 | 14 |
def file_save(file_, prefix='img', ext='jpeg'): |
10 | 15 |
ext = os.path.splitext(file_.name)[-1] or ext |
11 |
- path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext) |
|
12 |
- if default_storage.exists(path): |
|
13 |
- default_storage.delete(path) |
|
14 |
- default_storage.save(path, file_) |
|
15 |
- return path, ext |
|
16 |
+ |
|
17 |
+ photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=calculate_md5(file_)) |
|
18 |
+ |
|
19 |
+ if not photo.photo_path: |
|
20 |
+ path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext) |
|
21 |
+ if default_storage.exists(path): |
|
22 |
+ default_storage.delete(path) |
|
23 |
+ default_storage.save(path, file_) |
|
24 |
+ |
|
25 |
+ photo.photo_path = path |
|
26 |
+ photo.save() |
|
27 |
+ |
|
28 |
+ return photo.photo_path, ext |